
PLUG.Platform = PLUG_PLATFORM_SHARED

PLUG.ClassName = "sh_notices"
PLUG.PrintName = "GManage Notices Plug"
PLUG.Author = "thomasfn"

if (SERVER) then

	function PLUG:AddHooks()
		plugs.Hook( PLUG_PLATFORM_SERVER, "Think" )
	end
	
	local default = 300
	local default_notice = "Please be patient whilst the server is setup."
	
	function PLUG:GetNoticeDelay()
		return plugs.Call( "GetServerValue", "notice_delay", default )
	end
	
	function PLUG:SetNoticeDelay( del )
		del = math.Clamp( del or 0, 15, 60*60 ) -- No less than 15 seconds, no more than 1 hour
		plugs.Call( "SetServerValue", "notice_delay", del )
		return del
	end
	
	function PLUG:AddNotice( text )
		local tmp = plugs.Call( "GetServerValue", "notice_list", {} )
		table.insert( tmp, text )
		plugs.Call( "SetServerValue", "notice_list", tmp )
	end
	
	function PLUG:RemoveNotice( id )
		local tmp = plugs.Call( "GetServerValue", "notice_list", {} )
		if (!id) then return end
		local n = tmp[ id ]
		if (!n) then return end
		table.remove( tmp, id )
		plugs.Call( "SetServerValue", "notice_list", tmp )
		return n
	end
	
	function PLUG:ChooseNotice()
		local tbl = plugs.Call( "GetServerValue", "notice_list", { default_notice } )
		if ((!tbl) || (table.Count( tbl ) == 0)) then return default_notice end
		return table.Random( tbl )
	end
	
	function PLUG:Think()
		self.NextNotice = self.NextNotice or 0
		if (CurTime() >= self.NextNotice) then
			self.NextNotice = CurTime() + self:GetNoticeDelay()
			self:SendNotice( self:ChooseNotice(), nil, true )
		end
	end

	function PLUG:SendNotice( text, ply, chatnotice )
		umsg.Start( "gmanage", ply )
			umsg.String( "notice" )
			umsg.String( text )
		umsg.End()
		// PrintMessage( HUD_PRINTCONSOLE, "GManage: " .. text )
		if (chatnotice) then plugs.Call( "SendChatNotice", text ) end
	end
	
	function PLUG:DoConCommand( ply, com, args )
		if (string.Left( com, string.len( "notice_" ) ) != "notice_") then return end
		if (!ply:HasPriv( "manage_notices" )) then return end
		if (com == "notice_getall") then
			datastream.StreamToClients( ply, "gmanage", { "noticelist", plugs.Call( "GetServerValue", "notice_list", {} ) } )
			return true
		end
		if (com == "notice_add") then
			local notice = table.concat( args, " " )
			plugs.Call( "AddNotice", notice )
			ply:Log( "notices", "Added '" .. notice .. "'" )
			plugs.CallHalt( "SendChatNotice", ply:Nick() .. " added a new notice!", true )
			ply:PrintMessage( HUD_PRINTTALK, "Notice added!" )
			self:DoConCommand( ply, "notice_getall" )
			return true
		end
		if (com == "notice_remove") then
			local notice = tonumber( args[1] or "1" ) or 1
			local removed = plugs.Call( "RemoveNotice", notice )
			if (!removed) then
				ply:PrintMessage( HUD_PRINTTALK, "Invalid notice!" )
				return true
			end
			ply:Log( "notices", "Removed '" .. removed .. "'" )
			plugs.CallHalt( "SendChatNotice", ply:Nick() .. " removed a notice!", true )
			ply:PrintMessage( HUD_PRINTTALK, "Notice removed!" )
			self:DoConCommand( ply, "notice_getall" )
			return true
		end
	end
	
	function PLUG:IsValidPriv( priv )
		if (priv == "manage_notices") then return true end
	end

end

if (CLIENT) then

	function PLUG:UserMessage( tag, um )
		if (tag == "notice") then
			local notice = vgui.Create( "GMAN_Notice" )
			notice:Setup( um:ReadString() )
			return true
		end
	end
	
	function PLUG:GetPrivDictionary()
		return { manage_notices = "Manage Notices" }
	end

	function PLUG:Initialize()
	
		local PANEL = {}
		function PANEL:Setup( text )
			self.StartTime = CurTime()
			self.EndTime = CurTime() + 7
			self.Text = text
		end
		function PANEL:GetTrans()
			return math.Clamp( (CurTime() - self.StartTime) / (self.EndTime - self.StartTime), 0, 1 )
		end
		local col = Color( 255, 255, 255 )
		function PANEL:Paint()
			local t = self:GetTrans()
			local a = 220
			if (t < 0.15) then a = (t/0.15)*220 end
			if (t >= 0.85) then a = (1-((t-0.85)/0.15))*220 end
			surface.SetDrawColor( 50, 50, 50, a )
			surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			surface.SetDrawColor( 255, 255, 255, a )
			surface.DrawLine( 0, self:GetTall()-1, self:GetWide(), self:GetTall()-1 )
			col.a = a
			draw.SimpleText( self.Text or "ERROR", "ScoreboardText", self:GetWide()*0.5, self:GetTall()*0.5, col, 1, 1 )
		end
		function PANEL:PerformLayout()
			self:SetPos( 0, 0 )
			surface.SetFont( "ScoreboardText" )
			local tw, th = surface.GetTextSize( "GManage rules" )
			self:SetSize( ScrW(), th + 10 )
		end
		function PANEL:Think()
			if (self:GetTrans() >= 1) then self:Remove() end
		end
		vgui.Register( "GMAN_Notice", PANEL, "PANEL" )
		
	end
	
	local NOTWIN
	
	function PLUG:DataStream( tab )
		if (tab[1] == "noticelist") then
			self.Notices = tab[2]
			if (NOTWIN && NOTWIN:IsValid()) then
				plugs.Call( "BuildServerPanel", NOTWIN, "notice_edit" )
			end
		end
	end
	
	local newaction = { { "notice_edit", "Notices" } }
	function PLUG:GetServerActions()
		return newaction
	end
	
	function PLUG:BuildServerPanel( window, acname )
		if (acname == "notice_edit") then
			NOTWIN = window
		else
			NOTWIN = nil
		end
	end
	
	function PLUG:BuildActionPanel( pn, action )
		if (action == "notice_edit") then
			local w, h = pn:GetWide(), pn:GetTall()
			
			local tbl = vgui.Create( "DListView", pn )
			tbl:SetPos( 5, 5 )
			tbl:SetSize( pn:GetWide()-10, pn:GetTall()-60 )
			tbl:AddColumn( "Notice" )
			
			for k, v in pairs( self.Notices or {} ) do
				local row = tbl:AddLine( v )
				row.ID = k
			end
			
			local selID
			
			function tbl:OnRowSelected( row )
				local line = self:GetSelected()[ 1 ]
				selID = line.ID
			end
			
			local btn = vgui.Create( "DButton", pn )
			btn:SetPos( 5, pn:GetTall()-50 )
			btn:SetSize( pn:GetWide()-10, 20 )
			btn:SetText( "Get Notice List" )
			function btn:DoClick()
				plugs.Call( "SendCommand", "notice_getall" )
			end
			
			local btn = vgui.Create( "DButton", pn )
			btn:SetPos( 5, h-25 )
			btn:SetText( "Remove Selected" )
			btn:SetSize( w*0.5 - 10, 20 )
			function btn:DoClick()
				plugs.Call( "SendCommand", "notice_remove", selID )
			end
			
			local btnb = vgui.Create( "DButton", pn )
			btnb:SetPos( w*0.5 + 5, h-25 )
			btnb:SetText( "Add New" )
			btnb:SetSize( w*0.5 - 10, 20 )
			function btnb:DoClick()
				plugs.Call( "OpenNewNoticeWindow" )
			end
		end
	end
	
	function PLUG:OpenNewNoticeWindow()
		local win = vgui.Create( "DFrame" )
		win:SetSize( ScrW()*0.75, ScrH()*0.25 )
		win:Center()
		win:SetTitle( "GManage - Add New Notice" )
		win:SetDraggable( true )
		win:ShowCloseButton( true )
		
		function win:Paint()
			local w, h = self:GetWide(), self:GetTall()
			surface.SetDrawColor( color_black )
			surface.DrawRect( 0, 0, w, h )
			surface.SetDrawColor( color_white )
			surface.DrawOutlinedRect( 0, 0, w, h )
			surface.DrawLine( 0, 25, w, 25 )
		end
		
		local txt = vgui.Create( "DTextEntry", win )
		txt:SetPos( 5, 30 )
		txt:SetSize( win:GetWide()-10, 20 )
		
		local btn = vgui.Create( "DImageButton", win )
		btn:SetImage( "gmanage/ico_add" )
		btn:SetSize( 64, 64 )
		btn:SetPos( 0, 55 )
		btn:CenterHorizontal()
		function btn:DoClick()
			win:Remove()
			local notice = txt:GetValue()
			plugs.Call( "SendCommand", "notice_add", unpack( string.Explode( " ", notice ) ) )
		end
		
		win:SetTall( 128 )
		win:MakePopup()
		win:DoModal()
	end

end